/*
 *      Assign.java
 *
 *      Copyright 2008 Pablo Nicolas Diaz Bilotto <pablonicolas.diaz@gmail.com>
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */
package ilanguage.iltokens.operations.arimethic;

import i386CodeGenerator.RegisterAssigner;
import ilanguage.iltokens.IL_SSA;
import ilanguage.iltokens.IL_SSA_TokenWrapper;
import ilanguage.iltokens.operations.OperationIL_SSA;
import ilanguage.iltokens.operations.Operations;
import ilanguage.iltokens.operations.TypeSafeTwoOperandIL_SSA;
import lexer.EntryType;

/**
 * The Class Assign.
 */
public class Assign extends TypeSafeTwoOperandIL_SSA {

	/**
	 * Instantiates a new assign.
	 *
	 * @param firstToken the first token
	 * @param secToken the sec token
	 */
	public Assign(IL_SSA firstToken, IL_SSA secToken) {
		super(firstToken, secToken);
	}

	/* (non-Javadoc)
	 * @see ilanguage.iltokens.IL_SSA#GenerateCode()
	 */
	public String GenerateCode() {
		 String firstArg = this.getFirstArg().getResultRegister();
	     String secondArg = this.getSecondArg().getResultRegister();
		 String codigo=  "\t; Comienzo de Asignacion\n";

		 if (this.getSecondArg() instanceof IL_SSA_TokenWrapper ) {
			if (this.solveTypes() ==EntryType.INT) {
				codigo += "\t\tmov " + firstArg + " , " + secondArg + "\n";
				}
			else {
				codigo += "\t\tfld " + secondArg + "\n";
				codigo += "\t\tfstp " + firstArg + "\n";
			}
		} else if (this.solveTypes() == EntryType.INT)
		    	 codigo+=assingINTGenerateCode(firstArg,secondArg);
		     else
		    	 codigo+=assingDOUBLEGenerateCode(firstArg,secondArg);

		 codigo+=  "\t; Fin de Asignacion\n\n";
	     return codigo;
	}

	/**
	 * Assing double generate code.
	 *
	 * @param firstArg the first arg
	 * @param secondArg the second arg
	 *
	 * @return the string
	 */
	private String assingDOUBLEGenerateCode(String firstArg, String secondArg) {
		return "\t\tfstp "+firstArg+"\n";
	}


	/**
	 * Assing int generate code.
	 *
	 * @param firstArg the first arg
	 * @param secondArg the second arg
	 *
	 * @return the string
	 */
	private String assingINTGenerateCode(String firstArg, String secondArg) {
		String codigo ="";
		if (RegisterAssigner.getInstance().esRegistro(secondArg)){
	    	 codigo+="\t\tmov "+firstArg+ " , "+ secondArg+"\n";
	    	 RegisterAssigner.getInstance().liberarRegistro(secondArg);
	     }
	     else {
	    	 String regAux = RegisterAssigner.getInstance().getRegistro();
	    	 codigo+= "\t\tmov "+regAux+" , "+secondArg+"\n";
	    	 codigo+= "\t\tmov "+firstArg+" , "+regAux+"\n";
		     RegisterAssigner.getInstance().liberarRegistro(regAux);
	     }
		return codigo;
	}


	/**
	 * (non-Javadoc)
	 *
	 * @see ilanguage.iltokens.operations.OperationToken#getOperationName()
	 */
	@Override
	public String getOperationName() {
		return Operations.ASSIGN.toString();
	}

	public boolean isDiscartable() {
		return OperationIL_SSA.discartable(getSecondArg());
	}

	public final EntryType solveTypes() {
		if (!this.isDiscartable()) {
            return EntryType.F(getFirstArg().solveTypes(),
            		getSecondArg().solveTypes());
		} else {
			return EntryType.NOTYPE;
		}
	}


}